package com.summer.processor;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.locks.ReentrantLock;

import org.apache.log4j.Logger;

import com.summer.bean.Accesstoken;
import com.summer.bean.MessagerEntity;
import com.summer.bean.MsgContent;
import com.summer.bean.Response;
import com.summer.common.MessagerQueue;
import com.summer.http.HttpRequestTemplate;
import com.summer.http.MethodType;
import com.summer.utils.PropertiesConfig;

import redis.clients.jedis.Jedis;

public class MessageTemplateSendAction extends ProcessorAction {
	
	private static final String apiUrl;
	private static final String redisAddress;
	private static final int redisPort;
	private static final String redisPassword;
	
	private String send_id;
	
	private Logger log = Logger.getLogger(MessageTemplateSendAction.class);
	
	
	static{
		PropertiesConfig propertiesConfig = new PropertiesConfig("system_config.properies");
		apiUrl = propertiesConfig.getString("apiUrl");
		redisAddress = propertiesConfig.getString("redisAddress");
		redisPort = propertiesConfig.getInt("redisPort");
		redisPassword = propertiesConfig.getString("redisPassword");
	}


	@Override
	public void doAction(String msg) {
		
		send_id = parseSendId(msg);
		String uri = apiUrl+"send/getcontent";
		HashMap<String,String> request = new HashMap<>();
		request.put("send_id", send_id);
		
		Response response = sendRequest(uri,request, Response.class, MethodType.POST);
		log.info("接口名：send/getcontent,response:"+response.toLog());
		
		if(1==response.getStatus()){
			MsgContent content = response.dataToT(MsgContent.class);CountDownLatch latch = new CountDownLatch(content.getQueues().size());
			
			WaitTask waitTask = new WaitTask(latch);
			waitTask.start();
			
			for(String queue : content.getQueues()) {
				new Thread(new TaskAction(content.getCgiURL(),queue,content,latch)).start();
			}
		}else{
			System.out.println(response.getInfo());
		}
		
	}
	
	public class WaitTask extends Thread{
		CountDownLatch latch ;
		
		public WaitTask(CountDownLatch latch){
			this.latch = latch;
		}
		
		@Override
		public void run() {
			try {
				latch.await();
				notificationResult("queues",0,0);
			} catch (InterruptedException e) { 
				e.printStackTrace();
			}
		}
	}
	
	private class TaskAction implements Runnable{
		private String uri;
		private String queueName;
		private String content;
		private CountDownLatch latch;
		private long time;

		private List<String> openIdList = null;
		private volatile int success=0;
		private volatile int fail=0;
		
		
		public TaskAction(String uri,String queueName,MsgContent content,CountDownLatch latch){
			this.queueName = queueName;
			this.content = content.getContent();
			this.latch = latch;
			this.uri = uri;
		}
		
		private MessagerEntity.Callback callback = new MessagerEntity.Callback(){
			
			final ReentrantLock lock  = new ReentrantLock(false);
			
			private void doAction(boolean isSuccess) throws InterruptedException{
				final ReentrantLock lock = this.lock;
		        lock.lockInterruptibly();
		        if(isSuccess)
		        	success++;
		        else
		        	fail++;

	        	if( (success+fail) == openIdList.size()){
			        try{
						time = System.currentTimeMillis()-time;
						log.info("队列名："+queueName+"耗时："+time+"毫秒");
						notificationResult(queueName,success,fail);
					}finally{
						latch.countDown();
					}
	        	}
				lock.unlock();
			}
			
			@Override
			public void successNotify() {
				try {
					doAction(true);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}

			@Override
			public void failNotify() {
				try {
					doAction(false);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		};
		
		@Override
		public void run() {
			MessagerQueue queue = MessagerQueue.build();
			
			time =System.currentTimeMillis();
			Jedis jedis = new Jedis(redisAddress, redisPort);
			if(redisPassword != null && !redisPassword.isEmpty())
				jedis.auth(redisPassword);
			jedis.connect();
			
			openIdList = new ArrayList<>();
			if(jedis.isConnected()) {
				openIdList = jedis.lrange(queueName, 0, -1);
			}
			jedis.close();
			
			for(String open_id : openIdList) {
				String tmpuri = uri + getAccesstoken().getAccess_token();
				String replaceContent = content.replace("{open_id}", open_id);
				queue.send(new MessagerEntity(tmpuri,replaceContent,callback));
			}
			
		}
	}
	
	
	private Accesstoken accesstoken;
	private Accesstoken getAccesstoken(){
		if(accesstoken==null || accesstoken.isOverdue()){
			String uri = apiUrl+"send/getaccesstoken";
			HashMap<String,String> request = new HashMap<>();
			request.put("send_id", send_id);
			Response response = sendRequest(uri,request, Response.class, MethodType.POST);
			log.info("接口名：send/getaccesstoken,response:"+response.toLog());
			accesstoken =  response.dataToT(Accesstoken.class);
		}
		return accesstoken;
	}
	
	private String parseSendId(String msg){
		return msg;
	}
	
	private void notificationResult(String type,int success,int fail){
		String uri = apiUrl+"send/send_result";
		HashMap<String,String> request = new HashMap<>();
		request.put("send_id", send_id);
		request.put("type", type);
		request.put("success", success+"");
		request.put("fail", fail+"");
		Response response = sendRequest(uri, request, Response.class, MethodType.POST);
		log.info("接口名：send/send_result,response:"+response.toLog());
	}
	
	private <T> T sendRequest(String uri,Object request,Class<T> responseType,MethodType methodType){
		HttpRequestTemplate http = new HttpRequestTemplate();
		return http.doExecute(uri, request, responseType, methodType);
	}
}
